﻿using Odebrecht.WpfControls.Helpers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Odebrecht.WpfControls
{
    [TemplatePart(Name = CustomProjectVisualElements.TablePART, Type = typeof(CustomDataGrid))]
    [TemplatePart(Name = CustomProjectVisualElements.ChartPART, Type = typeof(CustomDataGrid))]
    [TemplateVisualState(GroupName = CustomProjectVisualStates.ViewModeGroup, Name = CustomProjectVisualStates.ViewModeAll)]
    [TemplateVisualState(GroupName = CustomProjectVisualStates.ViewModeGroup, Name = CustomProjectVisualStates.ViewModeTableOnly)]
    [TemplateVisualState(GroupName = CustomProjectVisualStates.ViewModeGroup, Name = CustomProjectVisualStates.ViewModeGanttOnly)]
    public class CustomProject : Control
    {
        #region Fields

        public static readonly DependencyProperty CollectionViewSourceProperty = 
            DependencyProperty.Register("CollectionViewSource", typeof(CollectionViewSource), typeof(CustomProject), new PropertyMetadata(new PropertyChangedCallback(CollectionViewSourceChangedCallback)));
        public static readonly DependencyProperty IsAnimatedProperty = 
            DependencyProperty.Register("IsAnimated", typeof(bool), typeof(CustomProject), new PropertyMetadata(true));
        public static readonly DependencyProperty ViewModeProperty = 
            DependencyProperty.Register("ViewMode", typeof(CustomProjectViewMode), typeof(CustomProject), new PropertyMetadata(CustomProjectViewMode.All, new PropertyChangedCallback(ViewModeChangedCallback)));

        private CustomDataGrid _chartElement;
        private CustomDataGrid _tableElement;

        #endregion Fields

        #region Constructors

        static CustomProject()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomProject), new FrameworkPropertyMetadata(typeof(CustomProject)));
        }

        #endregion Constructors

        #region Properties

        [Browsable(true)]
        [Category("Odebrecht")]
        [Description("CollectionViewSource")]
        public CollectionViewSource CollectionViewSource
        {
            get { return (CollectionViewSource)GetValue(CollectionViewSourceProperty); }
            set { SetValue(CollectionViewSourceProperty, value); }
        }

        [Browsable(true)]
        [Category("Odebrecht")]
        [Description("IsAnimated")]
        public bool IsAnimated
        {
            get { return (bool)GetValue(IsAnimatedProperty); }
            set { SetValue(IsAnimatedProperty, value); }
        }

        [Browsable(true)]
        [Category("Odebrecht")]
        [Description("ViewMode")]
        public CustomProjectViewMode ViewMode
        {
            get { return (CustomProjectViewMode)GetValue(ViewModeProperty); }
            set { SetValue(ViewModeProperty, value); }
        }

        #endregion Properties

        #region Methods

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _tableElement = GetTemplateChild(CustomProjectVisualElements.TablePART) as CustomDataGrid;
            _chartElement = GetTemplateChild(CustomProjectVisualElements.ChartPART) as CustomDataGrid;

            if (_tableElement != null)
            {
                _tableElement.SelectionMode = DataGridSelectionMode.Extended;
                _tableElement.SelectionUnit = DataGridSelectionUnit.CellOrRowHeader;                
                _tableElement.IsSynchronizedWithCurrentItem = true;
                _tableElement.CanUserAddRows = false;
                _tableElement.AutoGenerateColumns = false;
                _tableElement.LoadingRow += TableElementLoadingRow;
                _tableElement.SelectedCellsChanged += TableElementSelectedCellsChanged;
            }

            if (_chartElement != null)
            {
                _chartElement.SelectionMode = DataGridSelectionMode.Extended;
                _chartElement.SelectionUnit = DataGridSelectionUnit.CellOrRowHeader;
                _chartElement.IsSynchronizedWithCurrentItem = true;
                _chartElement.CanUserAddRows = false;
                _chartElement.AutoGenerateColumns = false;
                _chartElement.SetBinding(CustomDataGrid.ItemsSourceProperty, new Binding("CollectionOfTarefa.View"));
            }

            SetViewModeState(this.ViewMode);
        }

        private void TableElementSelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {
            if (e.AddedCells.Count == 1)
            {
                DataGridCellInfo cellInfo = e.AddedCells[0];
                var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
                if (cellContent != null)
                {
                    var dataGridCell = (DataGridCell)cellContent.Parent;
                    dataGridCell.LostFocus += TableElementDataGridCellLostFocus;
                    var result = SetDatePickerButtonVisible(dataGridCell, true);
                    //if (result)
                    //{
                    //    Debug.WriteLine("GotFocus");
                    //}
                }
            }
        }

        private void TableElementDataGridCellLostFocus(object sender, RoutedEventArgs e)
        {
            var dataGridCell = sender as DataGridCell;
            dataGridCell.LostFocus -= TableElementDataGridCellLostFocus;
            var result = SetDatePickerButtonVisible(dataGridCell, false);
            //if (result)
            //{
            //    Debug.WriteLine("LostFocus");
            //}
        }

        private bool SetDatePickerButtonVisible(DataGridCell dataGridCell, bool isButtonVisible)
        {
            if (dataGridCell.Content is ContentPresenter)
            {
                var contentPresenter = dataGridCell.Content as ContentPresenter;

                var listOfDatePicker = CustomVisualTreeHelper.FindVisualChildren<CustomDatePicker>(contentPresenter);

                if (listOfDatePicker.Count() == 1)
                {
                    var datePicker = listOfDatePicker.First();
                    datePicker.IsButtonVisible = isButtonVisible;
                    return true;
                }
            }
            return false;
        }        

        protected virtual void CollectionViewSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var collectionViewSource = e.NewValue as CollectionViewSource;

            if (collectionViewSource.Source is IEnumerable<TaskBase> == false)
            {
                throw new ArgumentException("CollectionViewSource deve ser do tipo IEnumerable<TaskBase>");
            }
        }

        protected virtual void ViewModeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            SetViewModeState((CustomProjectViewMode)e.NewValue);
        }

        private static void CollectionViewSourceChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var customProject = sender as CustomProject;
            customProject.Dispatcher.Invoke(new Action(() =>
            {
                customProject.CollectionViewSourceChanged(sender, e);
            }));
        }

        private static void ViewModeChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var customProject = sender as CustomProject;
            customProject.Dispatcher.Invoke(new Action(() =>
            {
                customProject.ViewModeChanged(sender, e);
            }));
        }

        private void SetViewModeState(CustomProjectViewMode viewMode)
        {
            switch (ViewMode)
            {
                case CustomProjectViewMode.All:
                    VisualStateManager.GoToState(this, CustomProjectVisualStates.ViewModeAll, IsAnimated);
                    break;
                case CustomProjectViewMode.TableOnly:
                    VisualStateManager.GoToState(this, CustomProjectVisualStates.ViewModeTableOnly, IsAnimated);
                    break;
                case CustomProjectViewMode.GanttOnly:
                    VisualStateManager.GoToState(this, CustomProjectVisualStates.ViewModeGanttOnly, IsAnimated);
                    break;
                default:
                    throw new ArgumentException("Tipo inválido");
            }
        }

        private void TableElementLoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.Header = (e.Row.GetIndex() + 1).ToString();
        }

        #endregion Methods
    }
}